package com.sakura.oj.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sakura.oj.common.BaseResponse;
import com.sakura.oj.common.ErrorCode;
import com.sakura.oj.common.ResultUtils;
import com.sakura.oj.exception.BusinessException;
import com.sakura.oj.exception.ThrowUtils;
import com.sakura.oj.model.dto.solution.SolutionAddRequest;
import com.sakura.oj.model.dto.solution.SolutionQueryRequest;
import com.sakura.oj.model.entity.ProblemSolution;
import com.sakura.oj.model.entity.SolutionTag;
import com.sakura.oj.model.entity.User;
import com.sakura.oj.model.vo.ProblemSolutionVo;
import com.sakura.oj.model.vo.RecentlySolutionVo;
import com.sakura.oj.service.ProblemSolutionService;
import com.sakura.oj.service.SolutionTagService;
import com.sakura.oj.service.UserService;
import com.sakura.oj.utils.UserHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 题目题解接口
 *
 * @author sakura
 */
@RestController
@RequestMapping("/problem/solution")
@Slf4j
@RequiredArgsConstructor
public class ProblemSolutionController {

    private final ProblemSolutionService problemSolutionService;

    private final UserService userService;

    private final SolutionTagService solutionTagService;

    /**
     * 分页获取题目列表（封装类）
     *
     * @param solutionQueryRequest {@link SolutionQueryRequest}
     * @return {@link BaseResponse}<{@link Page<ProblemSolution>}>
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<ProblemSolutionVo>> listProblemVOByPage(@RequestBody SolutionQueryRequest solutionQueryRequest) {
        long current = solutionQueryRequest.getCurrent();
        long size = solutionQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);

        // 创建分页对象
        Page<ProblemSolutionVo> page = new Page<>(current, size);

        // 使用综合查询，直接在SQL中处理所有条件（包括标签条件）
        Page<ProblemSolutionVo> problemPage = problemSolutionService.listProblemSolutionVoByPage(solutionQueryRequest, page);

        // 封装用户信息
        List<Long> userIds = problemPage.getRecords().stream().map(ProblemSolutionVo::getUserId).toList();

        if (userIds.isEmpty()) {
            return ResultUtils.success(problemPage);
        }

        List<User> users = userService.listByIds(userIds);
        Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));
        problemPage.getRecords().forEach(problemSolutionVo -> {
            User user = userMap.get(problemSolutionVo.getUserId());
            if (user != null) {
                problemSolutionVo.setUsername(user.getUserName());
                problemSolutionVo.setAvatar(user.getUserAvatar());
            }
        });

        return ResultUtils.success(problemPage);
    }

    /**
     * 发布题解
     *
     * @param addRequest {@link SolutionAddRequest}
     * @return 题解的id
     */
    @PostMapping("/publish")
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<Long> addSolution(@RequestBody @Validated SolutionAddRequest addRequest) {
        ProblemSolution problemSolution = new ProblemSolution();
        BeanUtil.copyProperties(addRequest, problemSolution);
        Long userId = UserHolder.getUserId();
        problemSolution.setUserId(userId);
        boolean solutionSave = problemSolutionService.save(problemSolution);
        if (!solutionSave) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "题解发布失败");
        }
        Long problemSolutionId = problemSolution.getId();
        log.info("用户 {} 发表了题解 {}", userId, problemSolution.getTitle());
        // 写入标签
        List<Long> tags = addRequest.getTags();
        if (tags != null && CollUtil.isNotEmpty(tags)) {
            List<SolutionTag> solutionTagList = tags.stream().map(tagId -> {
                SolutionTag solutionTag = new SolutionTag();
                solutionTag.setTagId(tagId);
                solutionTag.setSolutionId(problemSolutionId);
                return solutionTag;
            }).toList();
            boolean tagSave = solutionTagService.saveBatch(solutionTagList);
            if (!tagSave) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            }
        }
        return ResultUtils.success(problemSolutionId);
    }

    /**
     * 获取最近发布的题解列表
     *
     * @return {@link BaseResponse}<{@link List<RecentlySolutionVo>}>
     */
    @GetMapping("get/recently/list")
    public BaseResponse<List<RecentlySolutionVo>> getRecentlySolutionList() {
        List<RecentlySolutionVo> recentlySolutionList = problemSolutionService.getRecentlySolutionList();
        return ResultUtils.success(recentlySolutionList);
    }

    /**
     * 获取题解详情
     */
    @GetMapping("get/detail/{solutionId}")
    public BaseResponse<ProblemSolutionVo> getSolutionDetail(@PathVariable("solutionId") Long id) {
        ProblemSolution problemSolution = problemSolutionService.getById(id);
        if (problemSolution == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        User author = userService.getById(problemSolution.getUserId());
        ProblemSolutionVo problemSolutionVo = new ProblemSolutionVo();
        BeanUtil.copyProperties(problemSolution, problemSolutionVo);
        problemSolutionVo.setUsername(author.getUserName());
        problemSolutionVo.setAvatar(author.getUserAvatar());
        return ResultUtils.success(problemSolutionVo);
    }

}
